import groovy.json.JsonSlurper

/**
 * 网络请求工具类
 * 参考： https://www.cnblogs.com/JonaLin/p/11269465.html
 */
class HttpUtil {

    /**
     * 多文件上传的方法
     *
     * @param actionUrl ：上传的路径
     * @param uploadFilePaths ：需要上传的文件路径，数组
     * @return
     */
    @SuppressWarnings("finally")
    public static String uploadFile(String actionUrl, String[] uploadFilePaths) {
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";

        DataOutputStream dataOutputStream = null;
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;

        try {
            // http的连接类
            HttpURLConnection connection = (HttpURLConnection) new URL(actionUrl).openConnection();
            // 设置是否从httpUrlConnection读入，默认情况下是true;
            connection.setDoInput(true);
            // 设置是否向httpUrlConnection输出
            connection.setDoOutput(true);
            // Post 请求不能使用缓存
            connection.setUseCaches(false);
            // 设定请求的方法，默认是GET
            connection.setRequestMethod("POST");
            // 设置字符编码连接参数
            connection.setRequestProperty("Connection", "Keep-Alive");
            // 设置字符编码
            connection.setRequestProperty("Charset", "UTF-8");
            // 设置请求内容类型
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

            // 设置DataOutputStream
            dataOutputStream = new DataOutputStream(connection.getOutputStream());
            for (int i = 0; i < uploadFilePaths.length; i++) {
                String uploadFile = uploadFilePaths[i];
                String filename = uploadFile.substring(uploadFile.lastIndexOf("//") + 1);

                dataOutputStream.writeBytes(twoHyphens + boundary + end);
                dataOutputStream.writeBytes("Content-Disposition: form-data; " +
                        "name=\"file" + i + "\";filename=\"" + filename
                        + "\"" + end);
                dataOutputStream.writeBytes(end);
                FileInputStream fStream = new FileInputStream(uploadFile);
                int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                int length = -1;
                while ((length = fStream.read(buffer)) != -1) {
                    dataOutputStream.write(buffer, 0, length);
                }
                dataOutputStream.writeBytes(end);
                /* close streams */
                fStream.close();
            }
            dataOutputStream.writeBytes(twoHyphens + boundary + twoHyphens + end);
            /* close streams */
            dataOutputStream.flush();
            if (connection.getResponseCode() >= 300) {
                throw new Exception(
                        "HTTP Request is not success, Response code is " + connection.getResponseCode());
            }

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                inputStream = connection.getInputStream();
                inputStreamReader = new InputStreamReader(inputStream);
                reader = new BufferedReader(inputStreamReader);
                tempLine = null;
                resultBuffer = new StringBuffer();
                while ((tempLine = reader.readLine()) != null) {
                    resultBuffer.append(tempLine);
                    resultBuffer.append("\n");
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (dataOutputStream != null) {
                try {
                    dataOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStreamReader != null) {
                try {
                    inputStreamReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultBuffer.toString();
    }


    /**
     * 上传apk到蒲公英
     */
    static def uploadPGY(String url, String filePath, LinkedHashMap pramMap) {
        println("filePath=========================================" + filePath)
        //查找上传的apk文件
        def apkDir = new File(filePath)
        if (!apkDir.exists()) {
            throw new RuntimeException("apk output path not exists!")
        }

        println("apkDir=========================================" + apkDir)
        String filename = filePath.substring(filePath.lastIndexOf("\\") + 1);
        println("filename=========================================" + filename)
        pramMap.each { key, value ->
            println("$key==========================$value")
        }

        println "*************** start upload file ***************"

        def twoHyphens = "--"
        def boundary = "*********"
        def end = "\r\n"

        //模拟表单上传 multipart/form-data
        def conn = new URL(url).openConnection()
        conn.setRequestMethod('POST')
        conn.setRequestProperty("Connection", "Keep-Alive")
        conn.setRequestProperty("Charset", "UTF-8")
        conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary)
        conn.setDoInput(true)
        conn.setDoOutput(true)

        //添加参数：_api_key
        def sb = new StringBuilder()
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=_api_key")
        sb.append(end).append(end)
        sb.append(pramMap["_api_key"]).append(end)

        //添加参数：uKey
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=uKey")
        sb.append(end).append(end)
        sb.append(pramMap["uKey"]).append(end)

        //添加参数：buildInstallType
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=buildInstallType")
        sb.append(end).append(end)
        sb.append(pramMap["buildInstallType"]).append(end)

        //添加参数：buildPassword
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=buildPassword")
        sb.append(end).append(end)
        sb.append(pramMap["buildPassword"]).append(end)

        //添加参数：buildUpdateDescription
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=buildUpdateDescription")
        sb.append(end).append(end)
        sb.append(pramMap["buildUpdateDescription"]).append(end)

        //添加参数file: 需要上传的apk文件
        sb.append(twoHyphens).append(boundary).append(end)
        sb.append("Content-Disposition: form-data; name=file;filename=").append(filename)
        sb.append(end).append(end)

        def dos = new DataOutputStream(conn.getOutputStream())
        dos.writeBytes(sb.toString())
        dos.flush()
        sb.delete(0, sb.length())

        def fis = new FileInputStream(filePath)
        byte[] bf = new byte[8192]
        int len
        while ((len = fis.read(bf)) != -1) {
            dos.write(bf, 0, len)
        }
        sb.append(end)
        sb.append(twoHyphens).append(boundary).append(end)
        dos.writeBytes(sb.toString())

        dos.flush()
        fis.close()
        dos.close()
        conn.connect()

        def text = conn.getContent().text
        def resp = new JsonSlurper().parseText(text)

        println resp
        println "*************** upload finish ***************"

        return resp
    }

    public static void download(String url) {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setRequestMethod("GET");
        connection.setRequestProperty("Content-Type", "application/octet-stream");
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setUseCaches(false);// 忽略缓存
        connection.setRequestProperty("Charset", "UTF-8");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.connect();

        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            int contentLength = connection.getContentLength();
            System.out.println("文件的大小是:===============" + contentLength);
            InputStream is = connection.getInputStream();
            bis = new BufferedInputStream(is);
            FileOutputStream fos = new FileOutputStream("src\\file\\下载的图片.jpg");
            bos = new BufferedOutputStream(fos);
            int size = 0;
            byte[] buffer = new byte[1024];
            while ((size = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, size);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bis != null) {
                    bis.close();
                }
                if (bos != null) {
                    bos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

/**
 * GET
 * @param url
 * @return
 */
    public static String get(String url) {
        StringBuilder stringBuilder = new StringBuilder()
        def connection = new URL(url).openConnection()
        connection.setRequestMethod('GET')
        connection.doOutput = true

        // 取得输入流
        InputStream inputStream = connection.getInputStream()
        byte[] b = new byte[1024]
        int length = -1
        while ((length = inputStream.read(b)) != -1) {
            stringBuilder.append(new String(b, 0, length))
        }

        // 断开连接
        connection.disconnect()
        inputStream.close()

        println "$url\n返回================" + stringBuilder.toString()
        return stringBuilder.toString()
    }


/**
 * POST : application/x-www-form-urlencoded
 * @param url
 * @param pramMap
 * @return
 */
    public static String postUrlEncode(String url, HashMap pramMap) {
        //建立连接
        def connection = new URL(url).openConnection()

        //设置参数
        connection.setDoOutput(true)     //需要输出
        connection.setDoInput(true)      //需要输入
        connection.setUseCaches(false)   //不允许缓存
        connection.setRequestMethod("POST")      //设置POST方式连接

        //设置请求属性
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded")
        connection.setRequestProperty("Connection", "Keep-Alive")// 维持长连接
        connection.setRequestProperty("Charset", "UTF-8")

        //连接,也可以不用明文connect，使用下面的httpConn.getOutputStream()会自动connect
        connection.connect()

        //建立输入流，向指向的URL传入参数
        DataOutputStream dos = new DataOutputStream(connection.getOutputStream())

        //写入参数
        def pramSb = new StringBuilder()
        pramMap.eachWithIndex { key, value, position ->
            if (position != pramMap.size() - 1) {
                pramSb.append(key).append("=").append(URLEncoder.encode(value, "UTF-8")).append("&")
            } else {
                pramSb.append(key).append("=").append(URLEncoder.encode(value, "UTF-8"))
            }
        }
        println "$url\n参数为============================================" + pramSb.toString()
        dos.writeBytes(pramSb.toString())
        dos.flush()
        dos.close()

        //获得响应状态
        int resultCode = connection.getResponseCode()
        StringBuffer sb = new StringBuffer()
        if (HttpURLConnection.HTTP_OK == resultCode) {
            String readLine = new String()
            BufferedReader responseReader = new BufferedReader(
                    new InputStreamReader(connection.getInputStream(), "UTF-8")
            )
            while ((readLine = responseReader.readLine()) != null) {
                sb.append(readLine).append("\n")
            }
            responseReader.close()
            println("返回为==================================${sb.toString()}")
        }
        return sb.toString()
    }

}
